﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace decode
{
    class Cl_workflow
    {
        
        /// <summary>
        /// Langue choisie par l'utilisateur par défaut all
        /// </summary>
        private string langue = "all";
        /// <summary>
        /// Chrono pour calculer le temps
        /// </summary>
        private Stopwatch chrono;
        /// <summary>
        /// Delegate pour le chrono
        /// </summary>
        delegate void DLGC();
        /// <summary>
        /// event pour stoper le chrono
        /// </summary>
        private event DLGC evt;
        /// <summary>
        /// Sauvegarde du temps
        /// </summary>
        private string temps;


        /// <summary>
        /// Cherche la meileur clé probable pour le contenu
        /// </summary>
        /// <param name="contenu">text à décoder</param>
        /// <returns>le meileur Cl_decode</returns>
        public Cl_decode trouverCle(string contenu)
        {
            DLGC d1 = new DLGC(this.LancerChrono);
            evt = new DLGC(StopChrono);
            string echantillon;
            echantillon = echantillonner(contenu);

            //demarage du chrono
            Thread t1 = new Thread(new ThreadStart(d1.Invoke));
            t1.Start();


            //#######################################################################################
            List<Cl_decode> decodes = new List<Cl_decode>();
            
            for (int i = 0; i < 100000; i++)
            {

                Cl_decode decode = new Cl_decode(i, echantillon, langue);
                decodes.Add(decode);
            }

            //foreach (Cl_decode x in decodes)
            //{
                Parallel.ForEach(decodes, (x) =>
                {
                x.decoder();

                //}
                }
            );

            //IEnumerable<Cl_decode> selectMax =
            //    from decode in decodes
            //    select decode;
            //return  decodes.Where((Cl_decode y) => y.pourcent == pourcentMax);

            float pourcentMax = decodes.Max((Cl_decode max) => max.pourcent);
            Debug.WriteLine(pourcentMax);


            evt.Invoke();
            decodes.OrderByDescending((y) => y.pourcent).FirstOrDefault().seconde = temps;

            return decodes.OrderByDescending((y) => y.pourcent).FirstOrDefault();




            //#######################################################################################
            //idée optimisation créer un tableau avec pour index la clé puis instancier le décode dans la case correspondante 
            //string cle;
            //Cl_decode[] tableau = new Cl_decode[10000];

            //Parallel.For(0, 9999, (x) =>
            //{
            //    cle = ajouterZeroNonSignificatif(x.ToString(), 4);
            //    tableau[x] = new Cl_decode(cle, echantillon);
            //    tableau[x].decoder(departDeLaCle);


            //}
            //);
            //var meileur =
            //from p in tableau
            //orderby p.pourcent descending
            //select p;
            //List<Cl_decode> decodes = tableau.ToList();
            ////Cl_decode[] decodes = tableau.OrderByDescending((x) => x.pourcent).ToArray();
            ////Debug.WriteLine(tableau[2222]);
            //return decodes.OrderByDescending((y) => y.pourcent).FirstOrDefault();

            ////return tableau[2222];



        }

        

        /// <summary>
        /// Lance le chrono
        /// </summary>
        private void LancerChrono()
        {
            chrono = Stopwatch.StartNew();
        }


        /// <summary>
        /// Stoper les chrono
        /// </summary>
        private void StopChrono()
        {
            chrono.Stop();
            temps = chrono.Elapsed.Minutes +":"+ chrono.Elapsed.Seconds;

        }

        /// <summary>
        /// Selectionne 150 caractères de textEntier si il peut sinon tout le text
        /// </summary>
        /// <param name="textEntier">text à échantionner</param>
        /// <returns></returns>
        private string echantillonner(string textEntier)
        {
            int fin = 0;
            int debut = 0;

            if (textEntier.Length > 150)
            {
                fin = 150;
                Random r = new Random();
                debut = r.Next(0, textEntier.Length - 150);

            }
            else
            {
                fin = textEntier.Length;
                debut = 0;

            }

           
            Debug.WriteLine("debut du text: " + debut );
            return textEntier.Substring(debut, fin);


        }

        /// <summary>
        /// Constructeur surcharger
        /// </summary>
        /// <param name="languePara">choix de la langue, si la langue est null ou vide le choix all est appliqué</param>
        public Cl_workflow(string languePara)
        {
            if (languePara == null || languePara =="")
            {
                this.langue = "all";
            }
            else
            {
                this.langue = languePara;
            }
            
             
                    
        }

        /// <summary>
        /// obligation d'utiliser la surcharge
        /// </summary>
        private Cl_workflow() { }

        

       
    }
}
